package com.sino.dataworks.job;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dataworks_public.model.v20200518.GetInstanceStatusCountRequest;
import com.aliyuncs.dataworks_public.model.v20200518.GetInstanceStatusCountResponse;
import com.aliyuncs.dataworks_public.model.v20200518.ListInstancesRequest;
import com.aliyuncs.dataworks_public.model.v20200518.ListInstancesResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.utils.StringUtils;
import com.sino.dataworks.dto.InstanceEntityDto;
import com.sino.dataworks.dto.StatusCountDto;
import com.sino.dataworks.enums.DataWorksTaskStatus;
import com.sino.dataworks.util.DataworksUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.BeanUtils;

import java.time.LocalTime;
import java.util.*;

import static java.lang.Thread.sleep;

@Slf4j
public class QuartzPhoneWarningTask implements Job {

    static IAcsClient client = null;
    Map<String, String> warningMap = new HashMap<>();
    static Map<String, ListInstancesResponse.Data.Instance> instanceMap = new HashMap<>();

    static {
        String endPoint = System.getenv("ALIBABA_END_POINT");
        String regionId = System.getenv("ALIBABA_REGION_ID");
        if (StringUtils.isEmpty(endPoint)) {
            endPoint = "dataworks-public-vpc.res.cloud.cheryfs.cn";
        }
        String keyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String keySec = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        if (StringUtils.isEmpty(keyId)) {
            keyId = "ZR18OFackif3jKT7";
        }
        if (StringUtils.isEmpty(keySec)) {
            keySec = "Pfvaw2BOmDPC4zEu1UglDu87jCn5yi";
        }
        if (StringUtils.isEmpty(regionId)) {
            regionId = "cn-wuhu-qrhy-d01";
        }
        DefaultProfile profile = DefaultProfile.getProfile(
                regionId,
                keyId, // 替换为你的AccessKey ID
                keySec); // 替换为你的AccessKey Secret
        DefaultProfile.addEndpoint(regionId, "dataworks-public", endPoint);
        client = new DefaultAcsClient(profile);
    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext)  {
        warningMap.clear();
        Date newDate = DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, -1);
        String time = DateUtil.format(newDate, "yyyyMMdd");
        boolean flag = true;
        boolean isFirstWarning = true;
        boolean isNeedWarning = false;
        Date begin = null;
        Map<String,InstanceEntityDto> hasRerunMap=new HashMap<>();
        Map<String,InstanceEntityDto> hasWarningMap=new HashMap<>();
        Map<String,Integer> retryMap=new HashMap<>();
        try {
            while (flag) {
                LocalTime now = LocalTime.now();
                int currentHour = now.getHour();
                StatusCountDto statusCountDto = getStatusCount();
                log.info("当前时间：" +DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")+ "当前小时：" + currentHour + " " + JSON.toJSONString(statusCountDto));
                // 判断当前小时是否大于或等于7
                if (currentHour >= 7) {
                    flag = false;
                    log.info("当前时间已大于或等于7点");
                } else {
                    if (statusCountDto.getFailureCount() > 0) {
                        String bizDate = DateUtil.format(newDate, "yyyy-MM-dd");
                        String endTime = DateUtil.format(new Date(), "yyyy-MM-dd");
                       List<InstanceEntityDto> dtos= DataworksUtil.getInstance(DataWorksTaskStatus.FAILURE.getCode(),bizDate,endTime);
                       if (dtos.size()>0){
                           log.info("跑批有任务失败");
                           List<InstanceEntityDto> needReRun=new ArrayList<>();
                           List<InstanceEntityDto> dtoss=new ArrayList<>();
                           for (InstanceEntityDto dto:dtos){
                               if(!hasWarningMap.containsKey(dto.getNodeName())){
                                   dtoss.add(dto);
                               }else {
                                   log.info("已告过警："+dto.getNodeName()+"-不再告警");
                               }
                           }
                           for (InstanceEntityDto dto:dtoss){
                                 retryMap.put(dto.getNodeName(),retryMap.getOrDefault(dto.getNodeName(),0)+1);
                                 DataworksUtil.getInstanceLog(DataworksUtil.getInstancesByNodeId(String.valueOf(dto.getNodeId())).get(0).getInstanceId());
                                   if(!hasRerunMap.containsKey(dto.getNodeName())){
                                       needReRun.add(dto);
                                   }else {
                                       if(retryMap.get(dto.getNodeName())>=3){
                                           log.info("已经重跑过2次："+dto.getNodeName());
                                           hasWarningMap.put(dto.getNodeName(),dto);
                                           isNeedWarning=true;
                                       }else{
                                           needReRun.add(dto);
                                       }
                                   }
                           }
                           if (needReRun.size()>0){
                               hasRerunMap.putAll(DataworksUtil.reRun(needReRun));
//                               Map<String,Object> map=DataworksUtil.reRun(needReRun);
//                               if(map.get("code").toString().equals("false")){
//                                   isNeedWarning=true;
//                               }else{
//                                   Map<String,InstanceEntityDto> mp= (Map<String, InstanceEntityDto>) map.get("data");
//                                   hasRerunMap.putAll(mp);
//                               }
                           }
                       }
                      if(isNeedWarning){
                           if (isFirstWarning) {
                               isFirstWarning = false;
                               begin = DateUtil.date();
                               log.info("跑批任务有失败!电话告警");
                               DataworksUtil.phoneWarning(null);
                               isNeedWarning=false;
                           } else {
                               //30分钟后依然还有错误 继续电话告警
                               Date end = DateUtil.date();
                               long minutes = DateUtil.between(begin, end, DateUnit.MINUTE);
                               if (minutes > 30) {
                                   log.info("跑批任务有失败!电话告警");
                                   DataworksUtil.phoneWarning(null);
                                   begin =  DateUtil.date();
                                   isNeedWarning=false;
                               }
                           }
                       }
                     //   failureInstances(statusCountDto.getTotalCount());
                        //  flag=false;
                    }
                    if (statusCountDto.getFailureCount() == 0 && statusCountDto.getWaitResCount() == 0 && statusCountDto.getWaitTimeCount() == 0 && statusCountDto.getRunningCount() == 0) {
                        log.info("已无日跑批任务");
                        flag = false;
                    }
                    /*for (int i=1;i<=30;i++){
                         getData(i);
                        if(warningMap.containsKey(time)){
                            log.info("跑批任务有失败!电话报警");
                            phoneWarning();
                            flag=false;
                            break;
                        }
                    }*/
                    sleep(1000 * 60 * 5);
                }
            }
            log.info(time + "定时任务结束");
            hasRerunMap.clear();
            hasWarningMap.clear();
            retryMap.clear();
        } catch (Exception e) {
            DataworksUtil.phoneWarning(null);
            e.printStackTrace();
        }

    }

    private void failureInstances(Integer total) {
        int totalPage=(total+100-1/100);
        for (int i=1;i<=totalPage;i++){
            getData(i);
        }
    }

    private String getData(int page) {
        // 创建DefaultAcsClient实例并初始化
        StringBuffer stringBuffer = new StringBuffer();
        Date newDate = DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, -1);
        String startTime = DateUtil.format(newDate, "yyyy-MM-dd") + " 00:00:00";
        String endTime = DateUtil.format(newDate, "yyyy-MM-dd") + " 00:00:00";
        String time = DateUtil.format(newDate, "yyyyMMdd");
        // 创建API请求并设置参数
        ListInstancesRequest request = new ListInstancesRequest();
        request.setProjectId(10022L); // 替换为你的DataWorks项目名称
        request.setProjectEnv("PROD");
        request.setBeginBizdate(startTime);
        request.setEndBizdate(endTime);
        request.setPageSize(100);
        request.setPageNumber(page);
        // 可以根据需要设置更多参数，如pageNumber、pageSize等
        try {
            // 调用ListInstances方法
            ListInstancesResponse response = client.getAcsResponse(request);
            // 处理响应结果
            if (response != null && response.getSuccess()) {
                stringBuffer.append("第" + page + "页：" + JSON.toJSONString(response) + "\n");
                List<ListInstancesResponse.Data.Instance> instances = response.getData().getInstances();
                instances.forEach(instance -> {
                    if (instance.getStatus().equals("FAILURE")) {
                       log.info("失败实例:"+ instance.getInstanceId()+":实例名称:"+instance.getNodeName());
                    }
                });
            } else {
                log.info("Failed to list instances. Error code: " + response.getErrorCode() + ", Error message: " + response.getErrorMessage());
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return stringBuffer.toString();
    }



    private StatusCountDto getStatusCount() {
        // 创建DefaultAcsClient实例并初始化
        StatusCountDto statusCountDto = null;
        Date newDate = DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, -1);
        String time = DateUtil.format(newDate, "yyyy-MM-dd");
        GetInstanceStatusCountRequest request = new GetInstanceStatusCountRequest();
        request.setProjectId(10022L);
        request.setProjectEnv("PROD");
        request.setBizDate(time);
        try {
            // 调用GetInstanceStatusCount方法
            GetInstanceStatusCountResponse response = null;
            try {
                response = client.getAcsResponse(request);
            } catch (ClientException e) {
                throw new RuntimeException(e);
            }
            // 处理响应结果
            if (response != null) {
                Integer notRunCount = response.getStatusCount().getNotRunCount();
                Integer waitTimeCount = response.getStatusCount().getWaitTimeCount();
                Integer waitResCount = response.getStatusCount().getWaitResCount();
                Integer runningCount = response.getStatusCount().getRunningCount();
                Integer failureCount = response.getStatusCount().getFailureCount();
                Integer successCount = response.getStatusCount().getSuccessCount();
                Integer totalCount = response.getStatusCount().getTotalCount();
                log.info("未运行实例的数量" + notRunCount);
                log.info("等待资源实例的数量" + waitResCount);
                log.info("满足条件开始等待运行的实例数量" + waitTimeCount);
                log.info("运行中的实例的数量" + runningCount);
                log.info("失败的实例的数量" + failureCount);
                log.info("成功的实例的数量" + successCount);
                log.info("总的实例的数量" + totalCount);
                statusCountDto = new StatusCountDto();
                BeanUtils.copyProperties(response.getStatusCount(), statusCountDto);
            } else {
                log.info("Failed to get instance status count. Error code: " + response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusCountDto;
    }

    public static void main(String[] args) {
        String dateStr1 = "2024-06-29 08:16:23";
        Date date1 = DateUtil.parse(dateStr1);

        String dateStr2 = "2024-06-29 23:33:13";
        Date date2 = DateUtil.parse(dateStr2);;

        long betweenDay = DateUtil.between(date1, date2, DateUnit.MINUTE);

        System.out.println(DataWorksTaskStatus.FAILURE.getCode());
    }
}
